﻿#include "stdafx.h"
#include "skintoolbar.h"
#include "ToolBarSkin.h"



#define IS_STDBTN(button)        (((button).fsStyle&(TBSTYLE_SEP|TBSTYLE_CHECKGROUP))==TBSTYLE_BUTTON)
#define IS_CHECKBTN(button)      (((button).fsStyle&(TBSTYLE_SEP|TBSTYLE_CHECKGROUP))==TBSTYLE_CHECK)
#define IS_GROUPBTN(button)      (((button).fsStyle&(TBSTYLE_SEP|TBSTYLE_CHECKGROUP))==TBSTYLE_CHECKGROUP)
#define IS_DROPDOWN(button)      (((button).fsStyle&TBSTYLE_DROPDOWN)==TBSTYLE_DROPDOWN)
#define IS_SEPARATOR(button)     (((button).fsStyle&TBSTYLE_SEP)&&((button).idCommand==0))
#define IS_CONTROL(button)       (((button).fsStyle&TBSTYLE_SEP)&&((button).idCommand!=0))
#define IS_CHECKED(button)       (((button).fsState&TBSTATE_CHECKED)==TBSTATE_CHECKED)
#define IS_ENABLED(button)       (((button).fsState&TBSTATE_ENABLED)==TBSTATE_ENABLED)
#define IS_INDETERMINATE(button) (((button).fsState&TBSTATE_INDETERMINATE)==TBSTATE_INDETERMINATE)
#define IS_PRESSED(button)       (((button).fsState&TBSTATE_ENABLED)==TBSTATE_PRESSED)
#define IS_VISIBLE(button)       (((button).fsState&TBSTATE_HIDDEN)==0)
#define IS_WRAP(button)          (((button).fsState&TBSTATE_WRAP)==TBSTATE_WRAP)
CSkinToolBar::CSkinToolBar(void)
{
	//m_pToolBarSkin = GetSkin().GetToolBarSkin();
}

CSkinToolBar::~CSkinToolBar(void)
{
	HookWindow( (HWND)NULL);
}
BOOL CSkinToolBar::InstallSkin(HWND hWnd)
{
    if (!hWnd || !LoadSkin())
    {
        return FALSE;
    }
	HookWindow( (HWND)NULL);
	int r = HookWindow( hWnd );
	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0,  SWP_FRAMECHANGED|SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
}
BOOL CSkinToolBar::LoadSkin()
{
    CAutoEnableSkin a(m_bEnableSkin);
	m_pToolBarSkin = GetSkin().GetToolBarSkin();
    if (!m_pToolBarSkin)
    {
        return FALSE;
    }
	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
    return TRUE;
}
LRESULT CSkinToolBar::OnWndMsg(UINT msg,WPARAM wp,LPARAM lp)
{
	switch(msg)
	{
	case WM_MOUSELEAVE:
		OnMouseLeave();
		return 0;
	}
	return CSkinWnd::OnWndMsg(msg,wp,lp);
}
void CSkinToolBar::OnPaint()
{
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
	CRect rtClient;
	GetClientRect(rtClient);
	CPaintDC dc(pToolBar);
	CMemDC memDC(&dc,rtClient);
	DrawToolBar(&memDC);
	
}
void CSkinToolBar::OnNcPaint(HRGN rgn1)
{
	CToolBar *pToolBar = (CToolBar*)CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(reinterpret_cast<CWnd*>(pToolBar));
	pDC = pToolBar->GetWindowDC();
	CRect rtWindow;
	pToolBar->GetWindowRect(rtWindow);
	rtWindow.OffsetRect(-rtWindow.left,-rtWindow.top);

	HWND hParent = ::GetParent(m_hWnd);
	if(hParent)
	{
		CRect rtParent;
		::GetWindowRect(hParent,rtParent);
		rtWindow.right = rtParent.right;
	}

	m_pToolBarSkin->DrawImageSection(pDC,rtWindow,m_pToolBarSkin->m_imageBackground);
	pDC =  pToolBar->GetDC();
	CRect rtClient;
	GetClientRect(rtClient);
	CMemDC dc(pDC,rtClient);
	DrawToolBar(&dc);
}
void CSkinToolBar::OnMouseMove( UINT nFlags, const CPoint& point )
{
	Default();
	if((nFlags & MK_LBUTTON) == 0)
	{
		TRACKMOUSEEVENT tme;
		m_nHotItem = HitTest(point);
		m_nPressedItem = -1;
		tme.cbSize = sizeof(TRACKMOUSEEVENT);
		tme.dwFlags = TME_LEAVE;
		tme.hwndTrack = m_hWnd;
		TrackMouseEvent(&tme);
	}
	else if(nFlags & MK_LBUTTON)
	{
		TRACKMOUSEEVENT tme;
		m_nPressedItem = HitTest(point);
		m_nHotItem = -1;
		tme.cbSize = sizeof(TRACKMOUSEEVENT);
		tme.dwFlags = TME_LEAVE;
		tme.hwndTrack = m_hWnd;
		TrackMouseEvent(&tme);
	}
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(reinterpret_cast<CWnd*>(pToolBar));
	pDC =  pToolBar->GetDC();
	CRect rtClient;
	GetClientRect(rtClient);
	CMemDC dc(pDC,rtClient);
	DrawToolBar(&dc);
}
void CSkinToolBar::OnLButtonDown( UINT nFlags, const CPoint& point )
{
	Default();
	m_nPressedItem = HitTest(point);
	m_nHotItem = -1;
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(reinterpret_cast<CWnd*>(pToolBar));
	pDC =  pToolBar->GetDC();
	CRect rtClient;
	GetClientRect(rtClient);
	CMemDC dc(pDC,rtClient);
	DrawToolBar(&dc);
}
void CSkinToolBar::OnMouseLeave()
{
	m_nHotItem = -1;
	m_nPressedItem = -1;
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(reinterpret_cast<CWnd*>(pToolBar));
	pDC =  pToolBar->GetDC();
	CRect rtClient;
	GetClientRect(rtClient);
	CMemDC dc(pDC,rtClient);
	DrawToolBar(&dc);
}
void CSkinToolBar::OnLButtonUp( UINT nFlags, const CPoint& point )
{
	Default();
	m_nPressedItem = -1;
	m_nHotItem = HitTest(point);
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(reinterpret_cast<CWnd*>(pToolBar));
	pDC =  pToolBar->GetDC();
	CRect rtClient;
	GetClientRect(rtClient);
	CMemDC dc(pDC,rtClient);
	DrawToolBar(&dc);
}

UINT CSkinToolBar::HitTest( CPoint point )
{
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);
	return pToolBar->HitTest(&point);
}
void CSkinToolBar::DrawToolBar(CDC *pDC)
{
	CRect rtClient;
	GetClientRect(rtClient);
	CToolBarCtrl *pToolBar = (CToolBarCtrl*)CWnd::FromHandle(m_hWnd);

	int nItemCount = pToolBar->GetButtonCount();
	if(nItemCount <= 0)return;
	m_pToolBarSkin->DrawImageSection(pDC,rtClient,m_pToolBarSkin->m_imageBackground);

	CRect rcItem;
#ifdef _WIN64
	LONG_PTR dwStyle = GetWindowLongPtr(m_hWnd, GWL_STYLE);
#else
	DWORD dwStyle = GetWindowLong( m_hWnd, GWL_STYLE );
#endif
	int OldModule = pDC->SetBkMode(TRANSPARENT);
	CFont *pFont  = pToolBar->GetFont();
	CFont* pOldFont = pDC->SelectObject(pFont);
	CImageList *pImageList = pToolBar->GetImageList();
	CImageList *pImageListHot = pToolBar->GetHotImageList();
	CImageList *pImageListDisabled = pToolBar->GetDisabledImageList();
	TBBUTTON tbbutton;

	for(int i = 0 ; i < nItemCount ; i++)
	{
		pToolBar->GetButton(i,&tbbutton);
		pToolBar->GetItemRect(i,rcItem);
		UINT uState = pToolBar->GetState(i);
		if((uState & TBSTATE_ENABLED)  == TBSTATE_ENABLED)
		{
			if(m_nPressedItem == i)
				DrawItemEntry(pDC,i,rcItem,PRESSED);
			else if(m_nHotItem == i)
				DrawItemEntry(pDC,i,rcItem,HOVER);
			else
				DrawItemEntry(pDC,i,rcItem,NORMAL);	
		}
		else
		{
			DrawItemEntry(pDC,i,rcItem,DISABLED);
		}
		if(IS_SEPARATOR(tbbutton))
			continue;
		HICON hIcon ;
		hIcon = pImageList->ExtractIcon(tbbutton.iBitmap);

		CSize extent(0);
		if (hIcon)
		{
			ICONINFO iconinfo;
			if (::GetIconInfo(hIcon,&iconinfo))
			{
				BITMAP bmpinfo;
				if (::GetObject(iconinfo.hbmMask, sizeof(bmpinfo), &bmpinfo))
				{
					extent.cx = (int)bmpinfo.bmWidth;
					extent.cy = (int)bmpinfo.bmHeight;
					if (!iconinfo.hbmColor)
						extent.cy /= 2;
				}
				if (iconinfo.hbmMask)
				{
					::DeleteObject(iconinfo.hbmMask);
				}
				if (iconinfo.hbmColor)
				{
					::DeleteObject(iconinfo.hbmColor);
				}
			}
		}
		int x,y;
		x = rcItem.left + rcItem.Width() /2 -extent.cx/2;
		y = rcItem.top +rcItem.Height() /2 -extent.cy/2;
		if(tbbutton.iString)
			y = rcItem.top +3;
		if( !IS_CONTROL(tbbutton) && pImageList)
			pImageList->Draw(pDC,tbbutton.iBitmap,CPoint(x,y),ILD_TRANSPARENT);

		
		if ((HIWORD(tbbutton.iString) != 0) && (tbbutton.iString != -1))
		{
			CFont *pFont = pToolBar->GetFont();
			CFont *pOld = pDC->SelectObject(pFont);
			LPWSTR lpText = NULL;
			lpText = (LPWSTR)tbbutton.iString;
			CRect rtText;
			rtText = rcItem;
			rtText.top = y + extent.cy;
			DrawTextW(pDC->GetSafeHdc(),lpText,-1,rtText,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_NOPREFIX);
			pDC->SelectObject(pOld);
		}
	}

}
void CSkinToolBar::DrawItemEntry( CDC* pDC, int nIndex, const CRect& rcItem, int nState )
{
	if(nState == DISABLED)
	{
		if(!m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemDisabled))
			m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemNormal);
	}
	else if(nState == PRESSED)
	{
		if(!m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemPressed))
			m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemNormal);
	}
	else if(nState == HOVER)
	{
		if(!m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemHover))
			m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemNormal);
	}
	else
	{
		m_pToolBarSkin->DrawImageSection(pDC,rcItem,m_pToolBarSkin->m_imageItemNormal);
	}
}